"""
    metadata fields
"""

import time
import datetime
import Tkinter as tk



class MetaInputFrame(object):
    def __init__(self, root, field, name, changeable=True):
        self.root = root # Tkinter root
        self.field = field
        self.name = name
        self.changeable = changeable

        frame = tk.Frame(self.root, bd=1, relief=tk.SUNKEN)

        # Meta name
        tk.Label(frame, text=self.name).pack(side=tk.LEFT)

        # change checkbutton
        self.do_update = tk.BooleanVar()
        self.do_update_button = tk.Checkbutton(
            frame, variable = self.do_update
        )
        self.do_update_button.pack(side=tk.LEFT)

        if not self.changeable:
            self.do_update_button.select()
            self.do_update_button.config(state=tk.DISABLED)

        do_update = self.field.render(frame)
        print "do_update:", do_update
        if do_update:
            print "select"
            self.do_update_button.select()
            print self.do_update.get()
        else:
            self.do_update_button.deselect()

        if not self.changeable:
            tk.Label(
                frame,
                text="Info: This field is not change able."
            ).pack(side=tk.RIGHT)
            self.field.deactivate()

        if self.field.help_text:
            l = tk.Label(frame, text=self.field.help_text)
            l.pack(side=tk.RIGHT, fill=tk.X)

        frame.pack(fill=tk.X)


#------------------------------------------------------------------------------


class BaseField(object):
    def __init__(self, root, meta_name, fs_item_data, cfg):
        self.root = root
        self.meta_name = meta_name
        self.fs_item_data = fs_item_data
        self.cfg = cfg

    def merged_fs_item_data(self):
        merged_data = set([])
        for data in self.fs_item_data:
            if data:
                merged_data.update(data)

        merged_data = list(merged_data)
        merged_data.sort()
        return merged_data

    def deactivate(self):
        """ Deactivate the input widget """
        self.text.config(state=tk.DISABLED)


class TagField(BaseField):

    def __init__(self, *args, **kwargs):
        super(TagField, self).__init__(*args, **kwargs)

        self.help_text = "Comma separated words."

    def render(self, master):
        self.text = tk.Text(master, width = 79, height = 2)
        self.text.pack()

        tags = set([])
        for data in self.fs_item_data:
            if data != None:
                tags.update(data)

        tags = list(tags)
        tags.sort()
        data = ",".join(tags)

        if data:
            self.text.insert(tk.END, data)
            return True
        else:
            return False

    def get(self):
        text = self.text.get(1.0, tk.END)
        tags = set([i.strip() for i in text.split(",")])
        tags = list(tags)
        tags.sort()
        print "tags:", tags
        return tags


#------------------------------------------------------------------------------

from ScrolledText import ScrolledText
from defaultDialog import DefaultDialog

class AddItem(DefaultDialog):
    """
    Add a new item to a existing listbox
    """
    def __init__(self, parent, cfg, parent_listbox):
        self.cfg = cfg
        self.parent_listbox = parent_listbox
        DefaultDialog.__init__(self, parent)

    def setup_widgets(self):
        tk.Label(self, text="Add a new item:").pack()

        # Create textfield
        self.textfield = tk.Text(
            self, width = 79, height = 1
        )
        self.textfield.pack()

        self.bind("<Return>", self.save)

        # Create Buttons
        buttonframe = tk.Frame(self)

        button = tk.Button(buttonframe, text = "save", command = self.save)
        button.pack(side=tk.LEFT)

        button = tk.Button(buttonframe, text = "cancel", command = self.cancel)
        button.pack(side=tk.LEFT)

        buttonframe.pack(fill=tk.X)

        self.textfield.focus_set()

    def save(self, event=None):
        text = self.textfield.get(1.0, tk.END).strip()
        print "AddItem save(): %r" % text

        if text:
            listbox = self.parent_listbox

            listbox.insert(tk.END, text)

            max = len(listbox.get(0, tk.END)) # FIXME: Solle irgendwie einfach gehen
            listbox.selection_set(max-1)

        self.destroy()

class BaseChoiceField(BaseField):
    def __init__(self, root, meta_name, fs_item_data, cfg):
        self.root = root
        self.meta_name = meta_name
        self.fs_item_data = fs_item_data
        self.cfg = cfg

        if not meta_name in self.cfg["choice cache"]:
            self.cfg["choice cache"][meta_name] = []

        self.available_choices = self.cfg["choice cache"][meta_name]

        if self.selectmode == tk.MULTIPLE:
            self.help_text = "multiple choice field"
        else:
            self.help_text = "single choice field"

        print "avaiable choices:", self.available_choices

    def render(self, master):
        self.listbox = tk.Listbox(
            master, selectmode=self.selectmode,
            height=5, width=79,
            exportselection=tk.FALSE
        )
        self.listbox.pack()

        merged_data = self.merged_fs_item_data()
        print "MultipleChoiceField", merged_data

        # Update choice cache: Append new items
        for choice in merged_data:
            if choice not in self.available_choices:
                self.available_choices.append(choice)

        # insert all choiced into the listbox widget
        for index, txt in enumerate(self.available_choices):
            self.listbox.insert(tk.END, txt)
            if txt in merged_data:
                self.listbox.selection_set(index)

        button = tk.Button(master, text = "add", command = self.add)
        button.pack(side=tk.LEFT)

    def add(self):
        print "add"
        AddItem(self.root, self.cfg, self.listbox)

    def get(self):
        selection = []
        curselection = self.listbox.curselection()
        print "curselection: %s" % repr(curselection)

        existing_items = self.listbox.get(0, tk.END)

        for i in curselection:
            index = int(i) # i ist ein String
            selection.append(existing_items[index])

        return selection

class MultipleChoiceField(BaseChoiceField):
    selectmode=tk.MULTIPLE
class SingleChoiceField(BaseChoiceField):
    selectmode=tk.SINGLE


#------------------------------------------------------------------------------


class BaseDateField(BaseField):
    def __init__(self, root, meta_name, fs_item_data, cfg):
        self.root = root
        self.meta_name = meta_name
        self.fs_item_data = fs_item_data
        self.cfg = cfg

    def render(self, master):
        self.text = tk.Text(master, width = self.width, height = 1)
        self.text.pack()

        if not self.fs_item_data:
            date = None
        else:
            print "XXX", self.fs_item_data
            
            date = self.fs_item_data[0]
            print "date: %r" % date
            for new_date in self.fs_item_data[1:]:
                print "new date: %r" % new_date
                if new_date != None and new_date>date:
                    print "update"
                    date = new_date

        if date==None:
            # datetime.date.today or datetime.datetime.now
            date=self.current_time()

        print "use date: %r" % date
        data = date.strftime(self.date_format)
        print "data: %r" % data

        if data:
            self.text.insert(tk.END, data)
            return True
        else:
            return False

    def get(self):
        datetime_string = self.text.get(1.0, tk.END).strip()
        print "date string: %r" % datetime_string
        struct_time = time.strptime(datetime_string, self.date_format)
        timestamp = time.mktime(struct_time)

        # datetime or date
        result = self.datetime_obj.fromtimestamp(timestamp)
        return result


class DateField(BaseDateField):
    def __init__(self, *args, **kwargs):
        super(DateField, self).__init__(*args, **kwargs)

        self.date_format = self.cfg["date format"]["format"]
        self.date_verbose = self.cfg["date format"]["verbose"]
        self.help_text = "Date field (%s)" % self.date_verbose

        self.datetime_obj = datetime.date
        self.current_time = datetime.date.today

        self.width = 10


class DatetimeField(BaseDateField):
    def __init__(self, *args, **kwargs):
        super(DatetimeField, self).__init__(*args, **kwargs)

        self.date_format = self.cfg["datetime format"]["format"]
        self.date_verbose = self.cfg["datetime format"]["verbose"]
        self.help_text = "Datetime field (%s)" % self.date_verbose

        self.datetime_obj = datetime.datetime
        self.current_time = datetime.datetime.now

        self.width = 19



if __name__ == '__main__':
    print DateField.__name__